package org.jeecg.modules.netty.handler.lamp;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.corp.netty.lamp.LampAA55FramePkg;
import org.jeecg.modules.corp.netty.lamp.LampFrameContent;
import org.jeecg.modules.corp.netty.lamp.LampQueryOneResp;
import org.jeecg.modules.netty.CRC16Util;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class ByteToLampFrameDecoder extends ByteToMessageDecoder {


    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {


        int len = byteBuf.readableBytes();
        if (len < 1) {
            return;
        }

        //byteBuf.markReaderIndex();
        int magic = byteBuf.readUnsignedByte();
        if (LampFrameContent.QUERY_ONE_MAGIC_RESP == magic) {
            LampQueryOneResp pkg = execQueryOneComm(magic, byteBuf);
            list.add(pkg);
        } else {
            int magic2 = byteBuf.readUnsignedByte();
            magic = magic << 8 | magic2;
            if (LampFrameContent.AA55_MAGIC == magic) {
                LampAA55FramePkg pkg = execAA55Frame(magic, byteBuf);
                list.add(pkg);
            } else {
                int skiplen = byteBuf.readableBytes();
                byteBuf.skipBytes(skiplen);
                log.warn("收到帧头({}),跳过（{}）字节处理", Integer.toHexString(magic), skiplen);
            }
        }

        log.info("ByteToLampFrameDecoder.decode({}) is Complete!",Integer.toHexString(magic));
    }

    private LampQueryOneResp execQueryOneComm(int magic, ByteBuf byteBuf) {
        LampQueryOneResp frame = new LampQueryOneResp();
        frame.setMagic((short) magic);
        frame.setPlayloadlen(byteBuf.readUnsignedByte());
        frame.setDeviceAddr(byteBuf.readUnsignedInt());
        frame.setTgdk(byteBuf.readUnsignedByte());//调光端口
        frame.setTggnm(byteBuf.readUnsignedByte());//调光功能码
        frame.setTgz(byteBuf.readUnsignedByte());//调光值
        frame.setKgdk(byteBuf.readUnsignedByte());//开关端口
        frame.setKggnm(byteBuf.readUnsignedByte());//开关功能码
        frame.setKgzt(byteBuf.readUnsignedByte());//开关状态
        frame.setCjdk(byteBuf.readUnsignedByte());//采集端口
        frame.setCjgnm(byteBuf.readUnsignedByte());//采集功能码

        frame.setCjsjyxcd(byteBuf.readUnsignedByte());//采集数据有效长度
        for(short i=0;i<frame.getCjsjyxcd();i+=2){
            if(i==0){
                frame.setDyz(byteBuf.readUnsignedShort());//电压值
            }else if(i==2){
                frame.setDlz(byteBuf.readUnsignedShort());//电流值
            }else if(i==4){
                frame.setYgglz(byteBuf.readUnsignedShort());//有功功率值
            }else if(i==6){
                frame.setWgglz(byteBuf.readUnsignedShort());//无功功率值
            }else if(i==8){
                frame.setPlz(byteBuf.readUnsignedShort());//频率值
            }else if(i==10){
                frame.setWdz(byteBuf.readUnsignedShort());//温度值
            }else if(i==12) {
            }
        }
        frame.setCrc16(byteBuf.readUnsignedShort());//CRC16
        return frame;
    }

    private LampAA55FramePkg execAA55Frame(int magic, ByteBuf byteBuf) {
        LampAA55FramePkg frame = new LampAA55FramePkg();
        frame.setMagic(magic);
        frame.setPlayloadlen(byteBuf.readUnsignedShort());
        frame.setReserved(byteBuf.readUnsignedInt());
        frame.setCrc16(byteBuf.readUnsignedShort());
        frame.setDeviceAddr(byteBuf.readUnsignedInt());
        frame.setFunCode(byteBuf.readUnsignedByte());
        readParams(frame, byteBuf);
        return frame;
    }


    private void readParams(LampAA55FramePkg frame, ByteBuf byteBuf) {
        int len = frame.getPlayloadlen() - 5;
        if (len <= 0) {
            return;
        }
        Map<String, Number> pMap = new HashMap<>();
        frame.setPMap(pMap);
        int funCode = frame.getFunCode();
        switch (funCode) {
            case LampFrameContent.REG_FUN_CODE:
                while (len > 0) {
                    short sNo = byteBuf.readUnsignedByte();
                    len--;
                    if (sNo == 0x07) {
                        pMap.put(LampFrameContent.IMEI, byteBuf.readLong());
                        len -= 8;
                    } else if (sNo == 0x08) {
                        pMap.put(LampFrameContent.IMSI, byteBuf.readLong());
                        len -= 8;
                    } else if (sNo == 0x03) {
                        pMap.put(LampFrameContent.CSQ, byteBuf.readUnsignedByte());
                        len--;
                    } else if (sNo == 0x04) {//未知
                        //pMap.put(LampFrameContent.CSQ,byteBuf.readUnsignedByte());
                        byteBuf.readUnsignedByte();
                        len--;
                    } else if (sNo == 0x05) {
                        pMap.put(LampFrameContent.PCI, byteBuf.readUnsignedShort());
                        len -= 2;
                    } else {
                        if (len > 0) {
                            log.error("ByteToLampFrameDecoder.{} 解析错误，序列码：{},剩余数据：{}",
                                    Integer.toHexString(funCode), sNo,
                                    CRC16Util.bytes2HexStr(byteBuf.readBytes(len).array()));
                            len = 0;
                        }
                    }
                }
                break;
            default:
                log.error("ByteToLampFrameDecoder.{} 未知功能码：跳过剩余数据：{}",
                        Integer.toHexString(funCode),
                        CRC16Util.bytes2HexStr(byteBuf.readBytes(len).array()));
                len = 0;
                break;
        }

    }
}
